package org.learnaholic.ui.itemtable;

import java.awt.GridLayout;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.util.HashMap;
import java.util.Iterator;
import java.util.LinkedHashSet;
import java.util.Map;
import java.util.Set;

import javax.swing.JPanel;

public class LabelsTable extends JPanel
{
	private static final int default_cols = 20;
	private static final int default_rows = 15;
	
	private final LabelsTableModel model;
	private final GridLayout layout = new GridLayout(default_rows,default_cols);
	private final Map<String, TableCell> labelMap = new HashMap<String, TableCell>();

	private final ModelEventHandler modelEventHandler = new ModelEventHandler();
	private final MouseHandler mouseHandler = new MouseHandler();
	private final double ratioWidthOnHeight = (double)3/(double)2;
	
	public LabelsTable(LabelsTableModel model)
	{
		this.model	= model;
		setLayout(layout);
		model.addListener(modelEventHandler);
	}

	public void addModelListener(LabelsTableModelListener l)
	{
		model.addListener(l);
	}
	public void removeModelListener(LabelsTableModelListener l)
	{
		model.removeListener(l);
	}

	public TableCell getCell(String label)
	{
		return labelMap.get(label);
	}
	
	public void setAllSelected(boolean selected)
	{
		model.setAllSelected(selected);
	}
	
	/**
	 * 
	 */
	public void clear()
	{
		labelMap.clear();
		removeAll();
		layout.setColumns(default_cols);
		layout.setRows(default_rows);
	}
	public void addCells(Set<TableCell> cells)
	{
		int maxChars = 1;
		
		for (Iterator<TableCell> iterator = cells.iterator(); iterator.hasNext();)
		{
			TableCell label = iterator.next();
			String id = label.getId();
			model.add(id);
			label.addMouseListener(mouseHandler);
	        labelMap.put(id, label);
			String text = label.getText();
	        if(text.length() > maxChars)
	        {
	        	maxChars = text.length();
	        }
		}
		int cols = (int) Math.ceil(Math.sqrt(ratioWidthOnHeight * ((double)1 / (double)maxChars) * cells.size()));
		int rows = cells.size() / cols;
		layout.setColumns(cols);
		layout.setRows(rows);

		for (Iterator<TableCell> iterator = labelMap.values().iterator(); iterator.hasNext();)
		{
	        add(iterator.next());
		}
	}
	public void addItems(Set<String> items)
	{
		Set<TableCell> cells = new LinkedHashSet<TableCell>();
		
		for (Iterator<String> iterator = items.iterator(); iterator.hasNext();)
		{
			String str = iterator.next();
			cells.add( new TableCell(str));
		}
		
		addCells(cells);
	}
	
	public void removeItem(String item)
	{
		TableCell  cell = labelMap.remove(item);
		if(null != cell)
		{
			remove(cell);
		}
	}
	
	public Set<String> getSelected()
	{
		return model.getSelected();
	}
	
	private class ModelEventHandler implements LabelsTableModelListener
	{
		/**
		 * @param evt
		 */
		public void modelChanged(LabelsTableModelEvent evt)
		{
			for (Iterator<String> iterator = evt.getSelectedItems().iterator(); iterator.hasNext();)
			{
				labelMap.get(iterator.next()).setSelected(true);
			}
			for (Iterator<String> iterator = evt.getUnselectedItems().iterator(); iterator.hasNext();)
			{
				labelMap.get(iterator.next()).setSelected(false);
			}
		}
	}
	
	private class MouseHandler extends MouseAdapter
	{
		public void mousePressed(MouseEvent evt)
		{
			if (evt.getSource()instanceof TableCell)
			{
				TableCell cell = (TableCell) evt.getSource();
				
				model.setSelected(cell.getId(), !cell.isSelected());
			}
		}
	}

}
